﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using ExFlash.Tags;

namespace ExFlash.Records
{
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class TextRecord : ISwfSerializable, IReferenceCharacterId
    {
        private readonly ushort _advanceBits;
        private readonly ushort _gylphBits;
        private readonly TagCodes _code;

        public Boolean TextRecordType
        {
            get;
            protected set;
        }

        public Boolean StyleFlagsHasFont
        {
            get;
            protected set;
        }

        public Boolean StyleFlagsHasColor
        {
            get;
            protected set;
        }

        public Boolean StyleFlagsHasYOffset
        {
            get;
            protected set;
        }

        public Boolean StyleFlagsHasXOffset
        {
            get;
            protected set;
        }

        public ushort FontID
        {
            get;
            protected set;
        }

        public RGBRecord TextColor
        {
            get;
            protected set;
        }

        public short XOffset
        {
            get;
            protected set;
        }

        public short YOffset
        {
            get;
            protected set;
        }

        public ushort TextHeight
        {
            get;
            protected set;
        }

        public Byte GylphCount
        {
            get;
            protected set;
        }

        public GylphEntry[] GylphEntries
        {
            get;
            protected set;
        }

        public TextRecord(ushort gylphBits, ushort advanceBits, TagCodes code)
        {
            _advanceBits = advanceBits;
            _gylphBits = gylphBits;
            _code = code;
        }

        #region ISwfSerializable Members

        public void SwfDeserialize(BinaryBitReader reader)
        {
            TextRecordType = reader.ReadBoolean();

            reader.SkipBits(3);

            StyleFlagsHasFont = reader.ReadBoolean();
            StyleFlagsHasColor = reader.ReadBoolean();
            StyleFlagsHasYOffset = reader.ReadBoolean();
            StyleFlagsHasXOffset = reader.ReadBoolean();

            reader.AlignBits();

            if (StyleFlagsHasFont)
            {
                FontID = reader.ReadUInt16();
            }

            if (StyleFlagsHasColor)
            {
                TextColor = (_code == TagCodes.DefineText) ? new RGBRecord() : new RGBARecord();

                TextColor.SwfDeserialize(reader);
            }

            if (StyleFlagsHasXOffset)
            {
                XOffset = reader.ReadInt16();
            }

            if (StyleFlagsHasYOffset)
            {
                YOffset = reader.ReadInt16();
            }

            if (StyleFlagsHasFont)
            {
                TextHeight = reader.ReadUInt16();
            }

            GylphCount = reader.ReadByte();

            GylphEntries = new GylphEntry[GylphCount];

            for (int i = 0; i < GylphCount; i++)
            {
                GylphEntries[i] = new GylphEntry(_gylphBits, _advanceBits);
                GylphEntries[i].SwfDeserialize(reader);
            }

            reader.AlignBits();
        }

        public void SwfSerialize(byte[] arr, ref int offset)
        {
            throw new NotImplementedException();
        }

        #endregion

        public bool IsReferencing
        {
            get { return StyleFlagsHasFont; }
        }

        public ushort ReferencedId
        {
            get { return FontID; }
        }

        public IEnumerable<Type> ReferencedAttributes
        {
            get 
            { 
                return new List<Type> {typeof(FontTagAttribute)};
            }
        }
    }
}
